package com.huang.util;

import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.Base64;

import javax.servlet.http.HttpServletRequest;

import org.apache.logging.log4j.util.Strings;

import com.huang.constant.Common;
import com.huang.enums.AuthenticationMethodEnum;
import com.nimbusds.jose.JWSObject;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

/**
 * 请求工具类
 *
 * @author  han
 * @since  2022/2/12
 */
public class RequestUtils {

    public static String getGrantType() {
        HttpServletRequest request = RequestContextUtils.getRequest();
        return request.getParameter(Common.Token.GRANT_TYPE_KEY);
    }

    /**
     * 获取登录认证的客户端ID
     * <p>
     * 兼容两种方式获取OAuth2客户端信息（client_id、client_secret）
     * 方式一：client_id、client_secret放在请求路径中
     * 方式二：放在请求头（Request Headers）中的Authorization字段，且经过加密，例如 Basic Y2xpZW50OnNlY3JldA== 明文等于 client:secret
     *
     */
    public static String getOAuth2ClientId() {

        HttpServletRequest request = RequestContextUtils.getRequest();

        // 从请求路径中获取
        String clientId = request.getParameter(Common.Client.CLIENT_ID_KEY);
        if (StrUtil.isNotBlank(clientId)) {
            return clientId;
        }

        // 从请求头获取
        String basic = request.getHeader(Common.Token.TOKEN_HEADER_NAME);
        if (StrUtil.isNotBlank(basic) && basic.startsWith(Common.Token.BASIC_PREFIX)) {
            basic = basic.replace(Common.Token.BASIC_PREFIX, Strings.EMPTY);
            String basicPlainText = new String(Base64.getDecoder().decode(basic.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
            clientId = basicPlainText.split(":")[0]; //client:secret
        }
        return clientId;
    }

    /**
     * 解析JWT获取获取认证方式
     */
    public static String getAuthenticationMethod() {
        try {
            String refreshToken = RequestContextUtils.getRequest().getParameter(Common.Token.REFRESH_TOKEN_KEY);
            String payload = StrUtil.toString(JWSObject.parse(refreshToken).getPayload());
            JSONObject jsonObject = JSONUtil.parseObj(payload);

            String authenticationMethod = jsonObject.getStr(Common.Token.AUTHENTICATION_METHOD);
            if (StrUtil.isBlank(authenticationMethod)) {
                authenticationMethod = AuthenticationMethodEnum.USERNAME.getValue();
            }
            return authenticationMethod;
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
}
